source('../settings/settings.R')
source('commonFunctions.R')
persons <- SELECTED_SUBJECTS
all_Drive3 <- read.csv('..//data/processed/distancewise/TT1_Drive_3_30m_30m.csv')
all_Drive3$Subject <- as.factor(all_Drive3$Subject)
all_Drive3$logPerspiration <- log(all_Drive3$Perspiration)
mean_pp <- vector(mode="list", length=length(persons))
names(mean_pp) <- persons
std_pp <- vector(mode="list", length=length(persons))
names(std_pp) <- persons
# Mean (Turning)
mean_pp_seg0 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0) <- persons
mean_pp_seg0_1 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0_1) <- persons
mean_pp_seg0_2 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0_2) <- persons
mean_pp_seg0_3 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0_3) <- persons
mean_pp_seg0_4 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0_4) <- persons
# Mean (Straight)
mean_pp_seg1 <- vector(mode="list", length=length(persons))
names(mean_pp_seg1) <- persons
mean_pp_seg2 <- vector(mode="list", length=length(persons))
names(mean_pp_seg2) <- persons
mean_pp_seg3 <- vector(mode="list", length=length(persons))
names(mean_pp_seg3) <- persons
mean_pp_seg4 <- vector(mode="list", length=length(persons))
names(mean_pp_seg4) <- persons
mean_pp_max <- vector(mode="list", length=length(persons))
names(mean_pp_max) <- persons
# SD (Turning)
std_pp_seg0 <- vector(mode="list", length=length(persons))
names(std_pp_seg0) <- persons
std_pp_seg0_1 <- vector(mode="list", length=length(persons))
names(std_pp_seg0_1) <- persons
std_pp_seg0_2 <- vector(mode="list", length=length(persons))
names(std_pp_seg0_2) <- persons
std_pp_seg0_3 <- vector(mode="list", length=length(persons))
names(std_pp_seg0_3) <- persons
std_pp_seg0_4 <- vector(mode="list", length=length(persons))
names(std_pp_seg0_4) <- persons
# SD (Straight)
std_pp_seg1 <- vector(mode="list", length=length(persons))
names(std_pp_seg1) <- persons
std_pp_seg2 <- vector(mode="list", length=length(persons))
names(std_pp_seg2) <- persons
std_pp_seg3 <- vector(mode="list", length=length(persons))
names(std_pp_seg3) <- persons
std_pp_seg4 <- vector(mode="list", length=length(persons))
names(std_pp_seg4) <- persons
std_pp_max <- vector(mode="list", length=length(persons))
names(std_pp_max) <- persons
for(p in persons) {
pData <- all_Drive3[(all_Drive3$Subject==as.integer(p) | all_Drive3$Subject==p),]
pData_act3 <- pData[pData$Activity==3,]
pData_seg0 <- pData[pData$Phase==0,]
pData_seg0_1 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 100 & pData$Time < 200,]
pData_seg0_2 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 200 & pData$Time < 300,]
pData_seg0_3 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 300 & pData$Time < 400,]
pData_seg0_4 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 400 & pData$Time < 500,]
pData_seg1 <- pData[pData$Phase==1 & pData$Activity==3 & pData$Time < 110,]
pData_seg2 <- pData[pData$Phase==2 & pData$Activity==3 & pData$Time < 250,]
pData_seg3 <- pData[pData$Phase==3 & pData$Activity==3 & pData$Time < 350,]
pData_seg4 <- pData[pData$Phase==4 & pData$Activity==3,]
mean_pp[[p]] <- mean(pData_act3$ppLogNormalized)
std_pp[[p]] <- sd(pData$ppLogNormalized)
mean_pp_seg0[[p]] <- mean(pData_seg0$ppLogNormalized)
mean_pp_seg0_1[[p]] <- mean(pData_seg0_1$ppLogNormalized)
mean_pp_seg0_2[[p]] <- mean(pData_seg0_2$ppLogNormalized)
mean_pp_seg0_3[[p]] <- mean(pData_seg0_3$ppLogNormalized)
mean_pp_seg0_4[[p]] <- mean(pData_seg0_4$ppLogNormalized)
mean_pp_seg1[[p]] <- mean(pData_seg1$ppLogNormalized)
mean_pp_seg2[[p]] <- mean(pData_seg2$ppLogNormalized)
mean_pp_seg3[[p]] <- mean(pData_seg3$ppLogNormalized)
mean_pp_seg4[[p]] <- mean(pData_seg4$ppLogNormalized)
mean_pp_max[[p]] <- max(mean_pp_seg1[[p]], mean_pp_seg2[[p]], mean_pp_seg3[[p]], mean_pp_seg4[[p]])
std_pp_seg0[[p]] <- sd(pData_seg0$ppLogNormalized)
std_pp_seg0_1[[p]] <- sd(pData_seg0_1$ppLogNormalized)
std_pp_seg0_2[[p]] <- sd(pData_seg0_2$ppLogNormalized)
std_pp_seg0_3[[p]] <- sd(pData_seg0_3$ppLogNormalized)
std_pp_seg0_4[[p]] <- sd(pData_seg0_4$ppLogNormalized)
std_pp_seg1[[p]] <- sd(pData_seg1$ppLogNormalized)
std_pp_seg2[[p]] <- sd(pData_seg2$ppLogNormalized)
std_pp_seg3[[p]] <- sd(pData_seg3$ppLogNormalized)
std_pp_seg4[[p]] <- sd(pData_seg4$ppLogNormalized)
std_pp_max[[p]] <- max(std_pp_seg1[[p]], std_pp_seg2[[p]], std_pp_seg3[[p]], std_pp_seg4[[p]])
}
plt_AllAcc <- vector(mode="list", length=length(persons))
names(plt_AllAcc) <- persons
COLOR_ACC = "#02A3C8"
COLOR_PP = "#F28E8E"
COLOR_BRAKE = "#888888"
y1 <- list(
tickfont = list(color = COLOR_ACC),
title="Degree",
range=c(0, max(all_Drive3$Acceleration))
)
y2 <- list(
tickfont = list(color = COLOR_PP),
overlaying = "y",
side = "right",
title = "Log Perspiration",
showgrid = FALSE,
range=c(-0.6, 0.9)
# range=c(min(all_Drive3$ppLogNormalized), max(all_Drive3$ppLogNormalized))
)
for (p in persons) {
pData <- all_Drive3[(all_Drive3$Subject==as.integer(p) | all_Drive3$Subject==p),]
pData_seg0 <- pData[pData$Phase==0,]
pData_seg1 <- pData[pData$Phase==1 & pData$Activity==3 & pData$Time < 110,]
pData_seg2 <- pData[pData$Phase==2 & pData$Activity==3 & pData$Time < 250,]
pData_seg3 <- pData[pData$Phase==3 & pData$Activity==3 & pData$Time < 350,]
pData_seg4 <- pData[pData$Phase==4 & pData$Activity==3,]
plot_Acc <- plot_ly(pData, x = ~Time, height=400, width=900) %>%
# add_trace(name="Acceleration", y = ~Acceleration, type = 'scatter', mode = 'lines', line=list(width=1.5, color=COLOR_ACC)) %>%
add_trace(name="PP", y = ~ppLogNormalized, type = 'scatter', mode = 'lines', line=list(width=1.5, color=COLOR_PP), yaxis = "y2") %>%
add_segments(x = min(pData$Time), xend = max(pData$Time), y = mean_pp[[p]], yend = mean_pp[[p]],
yaxis = "y2", name="Avg. PP (straight)",
line=list(color="darkgray", dash = 'dot')) %>%
add_segments(x = min(pData$Time), xend = max(pData$Time), y = mean_pp_seg0[[p]], yend = mean_pp_seg0[[p]],
yaxis = "y2", name="Avg. PP (turning)",
line=list(color="black", dash = 'dot')) %>%
add_segments(x = min(pData_seg1$Time), xend = max(pData_seg1$Time), y = mean_pp_seg1[[p]], yend = mean_pp_seg1[[p]],
yaxis = "y2", name="Avg. PP (1st part)",
line=list(color="red", dash = 'dot')) %>%
add_segments(x = min(pData_seg2$Time), xend = max(pData_seg2$Time), y = mean_pp_seg2[[p]], yend = mean_pp_seg2[[p]],
yaxis = "y2", name="Avg. PP (2nd part)",
line=list(color="green", dash = 'dot')) %>%
add_segments(x = min(pData_seg3$Time), xend = max(pData_seg3$Time), y = mean_pp_seg3[[p]], yend = mean_pp_seg3[[p]],
yaxis = "y2", name="Avg. PP (3rd part)",
line=list(color="blue", dash = 'dot')) %>%
add_segments(x = min(pData_seg4$Time), xend = max(pData_seg4$Time), y = mean_pp_seg4[[p]], yend = mean_pp_seg4[[p]],
yaxis = "y2", name="Avg. PP (4th part)",
line=list(color="purple", dash = 'dot')) %>%
layout(
title=paste0("Subject #", p),
xaxis=list(title="Time [s]", range=c(0)),
yaxis=y1,
yaxis2=y2,
margin = list(l = 50, r = 50, b = 50, t = 50, pad = 4),
legend = list(x = 0.5, xanchor = "center", y = 0.2, bgcolor = "rgba(0,0,0,0)", title="Metric", orientation = "h"),
autosize = F
)
plt_AllAcc[[p]] <- plot_Acc
}
htmltools::tagList(plt_AllAcc)
NUMBER_OF_CLUSTERS = 3
color_darkpink = "#e75480"
CLUSTER_BRANCH_COLORS <- c("blue", "darkred", color_darkpink, "black")[1:NUMBER_OF_CLUSTERS]
CLUSTER_LABEL_COLORS <- c("blue", "darkred", color_darkpink, "black")[1:NUMBER_OF_CLUSTERS]
dfPP <- as.data.frame(cbind(
unlist(mean_pp),
unlist(std_pp),
unlist(mean_pp_seg0),
unlist(mean_pp_seg1),
unlist(mean_pp_seg2),
unlist(mean_pp_seg3),
unlist(mean_pp_seg4),
unlist(mean_pp_max),
unlist(std_pp_seg0),
unlist(std_pp_seg1),
unlist(std_pp_seg2),
unlist(std_pp_seg3),
unlist(std_pp_seg4),
unlist(std_pp_max),
unlist(mean_pp_seg0_1),
unlist(mean_pp_seg0_2),
unlist(mean_pp_seg0_3),
unlist(mean_pp_seg0_4),
unlist(std_pp_seg0_1),
unlist(std_pp_seg0_2),
unlist(std_pp_seg0_3),
unlist(std_pp_seg0_4)
))
names(dfPP) <- c("MeanPP", "StdPP",
"MeanPP_Seg0", "MeanPP_Seg1", "MeanPP_Seg2", "MeanPP_Seg3", "MeanPP_Seg4", "MeanPP_SegMax",
"StdPP_Seg0", "StdPP_Seg1", "StdPP_Seg2", "StdPP_Seg3", "StdPP_Seg4", "StdPP_SegMax",
"MeanPP_Seg0_1", "MeanPP_Seg0_2", "MeanPP_Seg0_3", "MeanPP_Seg0_4",
"StdPP_Seg0_1", "StdPP_Seg0_2", "StdPP_Seg0_3", "StdPP_Seg0_4")
behavioralMatrixClustering <- as.matrix(dfPP)
distMatrix <- dist(behavioralMatrixClustering)
hresults <- distMatrix %>% hclust(method="average")
hc <- hresults %>%
as.dendrogram %>%
set("nodes_cex", NUMBER_OF_CLUSTERS) %>%
set("labels_col", value = CLUSTER_LABEL_COLORS, k=NUMBER_OF_CLUSTERS) %>%
# set("leaves_pch", 19) %>%
# set("leaves_col", value = c("gray"), k=NUMBER_OF_CLUSTERS) %>%
set("branches_k_color", value=CLUSTER_BRANCH_COLORS, k=NUMBER_OF_CLUSTERS)
plot(hc)
legend("topright",
title="Drive=Motoric \nHierachical Clustering",
legend = c("Group 1", "Group 2", "Group 3"),
col = c("darkred", "pink" , "blue"),
pch = c(20,20,20), bty = "n", pt.cex = 1.5, cex = 0.8 ,
text.col = "black", horiz = FALSE, inset = c(0.4, 0.1))

Clustering with SD of PP
library(dendextend)
clusteringDf <- dfPP %>% select(StdPP)
NUMBER_OF_CLUSTERS = 3
color_darkpink = "#e75480"
CLUSTER_BRANCH_COLORS <- c("darkred", "blue", "red")[1:NUMBER_OF_CLUSTERS]
CLUSTER_LABEL_COLORS <- c("darkred", "blue", "red")[1:NUMBER_OF_CLUSTERS]
behavioralMatrixClustering <- as.matrix(clusteringDf)
rownames(behavioralMatrixClustering) <- paste0("#", persons)
distMatrix <- dist(behavioralMatrixClustering)
hresults <- distMatrix %>% hclust
hc <- hresults %>%
as.dendrogram %>%
set("nodes_cex", NUMBER_OF_CLUSTERS) %>%
set("labels_col", value = CLUSTER_LABEL_COLORS, k=NUMBER_OF_CLUSTERS) %>%
# set("leaves_pch", 19) %>%
# set("leaves_col", value = c("gray"), k=NUMBER_OF_CLUSTERS) %>%
set("branches_k_color", value=CLUSTER_BRANCH_COLORS, k=NUMBER_OF_CLUSTERS)
plot(hc)
legend("topright",
title="Drive=Motoric \nChange of Arousal",
legend = c("Exceptional SD" , "Low SD" , "High SD"),
col = c("darkred", "blue" , "red"),
pch = c(20,20,20), bty = "n", pt.cex = 1.5, cex = 0.8 ,
text.col = "black", horiz = FALSE, inset = c(0.0, 0.1))

library(cluster)
silhouette_score <- function(k){
km <- kmeans(clusteringDf, centers = k, nstart=25)
ss <- silhouette(km$cluster, dist(clusteringDf))
mean(ss[, 3])
}
k <- 2:10
avg_sil <- sapply(k, silhouette_score)
plot(k, type='b', avg_sil, xlab='Number of clusters', ylab='Average Silhouette Scores', frame=FALSE)

# Store clustering data
fPath <- str_interp("../data/processed/analysis/TT1_Drive_3_PP.csv")
dfx <- dfPP
dfx <- cbind(persons, dfx)
names(dfx) <- c("Subject" , names(dfPP))
write.csv(dfx, fPath, row.names = F)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CnNvdXJjZSgnLi4vc2V0dGluZ3Mvc2V0dGluZ3MuUicpCnNvdXJjZSgnY29tbW9uRnVuY3Rpb25zLlInKQpgYGAKCmBgYHtyfQpwZXJzb25zIDwtIFNFTEVDVEVEX1NVQkpFQ1RTCgphbGxfRHJpdmUzIDwtIHJlYWQuY3N2KCcuLi8vZGF0YS9wcm9jZXNzZWQvZGlzdGFuY2V3aXNlL1RUMV9Ecml2ZV8zXzMwbV8zMG0uY3N2JykKYWxsX0RyaXZlMyRTdWJqZWN0IDwtIGFzLmZhY3RvcihhbGxfRHJpdmUzJFN1YmplY3QpCmFsbF9Ecml2ZTMkbG9nUGVyc3BpcmF0aW9uIDwtIGxvZyhhbGxfRHJpdmUzJFBlcnNwaXJhdGlvbikKYGBgCgoKYGBge3J9Cm1lYW5fcHAgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcCkgPC0gcGVyc29ucwoKc3RkX3BwIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcCkgPC0gcGVyc29ucwoKIyBNZWFuIChUdXJuaW5nKQptZWFuX3BwX3NlZzAgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9zZWcwKSA8LSBwZXJzb25zCm1lYW5fcHBfc2VnMF8xIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfc2VnMF8xKSA8LSBwZXJzb25zCm1lYW5fcHBfc2VnMF8yIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfc2VnMF8yKSA8LSBwZXJzb25zCm1lYW5fcHBfc2VnMF8zIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfc2VnMF8zKSA8LSBwZXJzb25zCm1lYW5fcHBfc2VnMF80IDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfc2VnMF80KSA8LSBwZXJzb25zCgojIE1lYW4gKFN0cmFpZ2h0KQptZWFuX3BwX3NlZzEgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9zZWcxKSA8LSBwZXJzb25zCm1lYW5fcHBfc2VnMiA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX3NlZzIpIDwtIHBlcnNvbnMKbWVhbl9wcF9zZWczIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfc2VnMykgPC0gcGVyc29ucwptZWFuX3BwX3NlZzQgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9zZWc0KSA8LSBwZXJzb25zCm1lYW5fcHBfbWF4IDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfbWF4KSA8LSBwZXJzb25zCgojIFNEIChUdXJuaW5nKQpzdGRfcHBfc2VnMCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnMCkgPC0gcGVyc29ucwpzdGRfcHBfc2VnMF8xIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9zZWcwXzEpIDwtIHBlcnNvbnMKc3RkX3BwX3NlZzBfMiA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnMF8yKSA8LSBwZXJzb25zCnN0ZF9wcF9zZWcwXzMgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX3NlZzBfMykgPC0gcGVyc29ucwpzdGRfcHBfc2VnMF80IDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9zZWcwXzQpIDwtIHBlcnNvbnMKCiMgU0QgKFN0cmFpZ2h0KQpzdGRfcHBfc2VnMSA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnMSkgPC0gcGVyc29ucwpzdGRfcHBfc2VnMiA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnMikgPC0gcGVyc29ucwpzdGRfcHBfc2VnMyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnMykgPC0gcGVyc29ucwpzdGRfcHBfc2VnNCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnNCkgPC0gcGVyc29ucwpzdGRfcHBfbWF4IDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9tYXgpIDwtIHBlcnNvbnMKCmZvcihwIGluIHBlcnNvbnMpIHsKICBwRGF0YSA8LSBhbGxfRHJpdmUzWyhhbGxfRHJpdmUzJFN1YmplY3Q9PWFzLmludGVnZXIocCkgfCBhbGxfRHJpdmUzJFN1YmplY3Q9PXApLF0KICBwRGF0YV9hY3QzIDwtIHBEYXRhW3BEYXRhJEFjdGl2aXR5PT0zLF0KICAKICBwRGF0YV9zZWcwIDwtIHBEYXRhW3BEYXRhJFBoYXNlPT0wLF0KICBwRGF0YV9zZWcwXzEgPC0gcERhdGFbcERhdGEkQWN0aXZpdHk9PTAgJiBwRGF0YSRQaGFzZT09MCAmIHBEYXRhJFRpbWUgPiAxMDAgJiBwRGF0YSRUaW1lIDwgMjAwLF0KICBwRGF0YV9zZWcwXzIgPC0gcERhdGFbcERhdGEkQWN0aXZpdHk9PTAgJiBwRGF0YSRQaGFzZT09MCAmIHBEYXRhJFRpbWUgPiAyMDAgJiBwRGF0YSRUaW1lIDwgMzAwLF0KICBwRGF0YV9zZWcwXzMgPC0gcERhdGFbcERhdGEkQWN0aXZpdHk9PTAgJiBwRGF0YSRQaGFzZT09MCAmIHBEYXRhJFRpbWUgPiAzMDAgJiBwRGF0YSRUaW1lIDwgNDAwLF0KICBwRGF0YV9zZWcwXzQgPC0gcERhdGFbcERhdGEkQWN0aXZpdHk9PTAgJiBwRGF0YSRQaGFzZT09MCAmIHBEYXRhJFRpbWUgPiA0MDAgJiBwRGF0YSRUaW1lIDwgNTAwLF0KICAKICBwRGF0YV9zZWcxIDwtIHBEYXRhW3BEYXRhJFBoYXNlPT0xICYgcERhdGEkQWN0aXZpdHk9PTMgJiBwRGF0YSRUaW1lIDwgMTEwLF0KICBwRGF0YV9zZWcyIDwtIHBEYXRhW3BEYXRhJFBoYXNlPT0yICYgcERhdGEkQWN0aXZpdHk9PTMgJiBwRGF0YSRUaW1lIDwgMjUwLF0KICBwRGF0YV9zZWczIDwtIHBEYXRhW3BEYXRhJFBoYXNlPT0zICYgcERhdGEkQWN0aXZpdHk9PTMgJiBwRGF0YSRUaW1lIDwgMzUwLF0KICBwRGF0YV9zZWc0IDwtIHBEYXRhW3BEYXRhJFBoYXNlPT00ICYgcERhdGEkQWN0aXZpdHk9PTMsXQogIAogIG1lYW5fcHBbW3BdXSA8LSBtZWFuKHBEYXRhX2FjdDMkcHBMb2dOb3JtYWxpemVkKQogIHN0ZF9wcFtbcF1dIDwtIHNkKHBEYXRhJHBwTG9nTm9ybWFsaXplZCkKICAKICBtZWFuX3BwX3NlZzBbW3BdXSA8LSBtZWFuKHBEYXRhX3NlZzAkcHBMb2dOb3JtYWxpemVkKQogIG1lYW5fcHBfc2VnMF8xW1twXV0gPC0gbWVhbihwRGF0YV9zZWcwXzEkcHBMb2dOb3JtYWxpemVkKQogIG1lYW5fcHBfc2VnMF8yW1twXV0gPC0gbWVhbihwRGF0YV9zZWcwXzIkcHBMb2dOb3JtYWxpemVkKQogIG1lYW5fcHBfc2VnMF8zW1twXV0gPC0gbWVhbihwRGF0YV9zZWcwXzMkcHBMb2dOb3JtYWxpemVkKQogIG1lYW5fcHBfc2VnMF80W1twXV0gPC0gbWVhbihwRGF0YV9zZWcwXzQkcHBMb2dOb3JtYWxpemVkKQogIAogIG1lYW5fcHBfc2VnMVtbcF1dIDwtIG1lYW4ocERhdGFfc2VnMSRwcExvZ05vcm1hbGl6ZWQpCiAgbWVhbl9wcF9zZWcyW1twXV0gPC0gbWVhbihwRGF0YV9zZWcyJHBwTG9nTm9ybWFsaXplZCkKICBtZWFuX3BwX3NlZzNbW3BdXSA8LSBtZWFuKHBEYXRhX3NlZzMkcHBMb2dOb3JtYWxpemVkKQogIG1lYW5fcHBfc2VnNFtbcF1dIDwtIG1lYW4ocERhdGFfc2VnNCRwcExvZ05vcm1hbGl6ZWQpCiAgbWVhbl9wcF9tYXhbW3BdXSA8LSBtYXgobWVhbl9wcF9zZWcxW1twXV0sIG1lYW5fcHBfc2VnMltbcF1dLCBtZWFuX3BwX3NlZzNbW3BdXSwgbWVhbl9wcF9zZWc0W1twXV0pCiAgCiAgc3RkX3BwX3NlZzBbW3BdXSA8LSBzZChwRGF0YV9zZWcwJHBwTG9nTm9ybWFsaXplZCkKICBzdGRfcHBfc2VnMF8xW1twXV0gPC0gc2QocERhdGFfc2VnMF8xJHBwTG9nTm9ybWFsaXplZCkKICBzdGRfcHBfc2VnMF8yW1twXV0gPC0gc2QocERhdGFfc2VnMF8yJHBwTG9nTm9ybWFsaXplZCkKICBzdGRfcHBfc2VnMF8zW1twXV0gPC0gc2QocERhdGFfc2VnMF8zJHBwTG9nTm9ybWFsaXplZCkKICBzdGRfcHBfc2VnMF80W1twXV0gPC0gc2QocERhdGFfc2VnMF80JHBwTG9nTm9ybWFsaXplZCkKICAKICBzdGRfcHBfc2VnMVtbcF1dIDwtIHNkKHBEYXRhX3NlZzEkcHBMb2dOb3JtYWxpemVkKQogIHN0ZF9wcF9zZWcyW1twXV0gPC0gc2QocERhdGFfc2VnMiRwcExvZ05vcm1hbGl6ZWQpCiAgc3RkX3BwX3NlZzNbW3BdXSA8LSBzZChwRGF0YV9zZWczJHBwTG9nTm9ybWFsaXplZCkKICBzdGRfcHBfc2VnNFtbcF1dIDwtIHNkKHBEYXRhX3NlZzQkcHBMb2dOb3JtYWxpemVkKQogIHN0ZF9wcF9tYXhbW3BdXSA8LSBtYXgoc3RkX3BwX3NlZzFbW3BdXSwgc3RkX3BwX3NlZzJbW3BdXSwgc3RkX3BwX3NlZzNbW3BdXSwgc3RkX3BwX3NlZzRbW3BdXSkKfQoKYGBgCgpgYGB7cn0KcGx0X0FsbEFjYyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhwbHRfQWxsQWNjKSA8LSBwZXJzb25zCgpDT0xPUl9BQ0MgPSAiIzAyQTNDOCIKQ09MT1JfUFAgPSAiI0YyOEU4RSIKQ09MT1JfQlJBS0UgPSAiIzg4ODg4OCIKCnkxIDwtIGxpc3QoCiAgdGlja2ZvbnQgPSBsaXN0KGNvbG9yID0gQ09MT1JfQUNDKSwKICB0aXRsZT0iRGVncmVlIiwKICByYW5nZT1jKDAsIG1heChhbGxfRHJpdmUzJEFjY2VsZXJhdGlvbikpCikKeTIgPC0gbGlzdCgKICB0aWNrZm9udCA9IGxpc3QoY29sb3IgPSBDT0xPUl9QUCksCiAgb3ZlcmxheWluZyA9ICJ5IiwKICBzaWRlID0gInJpZ2h0IiwKICB0aXRsZSA9ICJMb2cgUGVyc3BpcmF0aW9uIiwKICBzaG93Z3JpZCA9IEZBTFNFLAogIHJhbmdlPWMoLTAuNiwgMC45KQogICMgcmFuZ2U9YyhtaW4oYWxsX0RyaXZlMyRwcExvZ05vcm1hbGl6ZWQpLCBtYXgoYWxsX0RyaXZlMyRwcExvZ05vcm1hbGl6ZWQpKQopCgpmb3IgKHAgaW4gcGVyc29ucykgewogIHBEYXRhIDwtIGFsbF9Ecml2ZTNbKGFsbF9Ecml2ZTMkU3ViamVjdD09YXMuaW50ZWdlcihwKSB8IGFsbF9Ecml2ZTMkU3ViamVjdD09cCksXQogIHBEYXRhX3NlZzAgPC0gcERhdGFbcERhdGEkUGhhc2U9PTAsXQogIHBEYXRhX3NlZzEgPC0gcERhdGFbcERhdGEkUGhhc2U9PTEgJiBwRGF0YSRBY3Rpdml0eT09MyAmIHBEYXRhJFRpbWUgPCAxMTAsXQogIHBEYXRhX3NlZzIgPC0gcERhdGFbcERhdGEkUGhhc2U9PTIgJiBwRGF0YSRBY3Rpdml0eT09MyAmIHBEYXRhJFRpbWUgPCAyNTAsXQogIHBEYXRhX3NlZzMgPC0gcERhdGFbcERhdGEkUGhhc2U9PTMgJiBwRGF0YSRBY3Rpdml0eT09MyAmIHBEYXRhJFRpbWUgPCAzNTAsXQogIHBEYXRhX3NlZzQgPC0gcERhdGFbcERhdGEkUGhhc2U9PTQgJiBwRGF0YSRBY3Rpdml0eT09MyxdCiAgCiAgcGxvdF9BY2MgPC0gcGxvdF9seShwRGF0YSwgeCA9IH5UaW1lLCBoZWlnaHQ9NDAwLCB3aWR0aD05MDApICU+JQogICAgIyBhZGRfdHJhY2UobmFtZT0iQWNjZWxlcmF0aW9uIiwgeSA9IH5BY2NlbGVyYXRpb24sIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMnLCBsaW5lPWxpc3Qod2lkdGg9MS41LCBjb2xvcj1DT0xPUl9BQ0MpKSAlPiUgCiAgICBhZGRfdHJhY2UobmFtZT0iUFAiLCB5ID0gfnBwTG9nTm9ybWFsaXplZCwgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdsaW5lcycsIGxpbmU9bGlzdCh3aWR0aD0xLjUsIGNvbG9yPUNPTE9SX1BQKSwgeWF4aXMgPSAieTIiKSAlPiUKICAgIGFkZF9zZWdtZW50cyh4ID0gbWluKHBEYXRhJFRpbWUpLCB4ZW5kID0gbWF4KHBEYXRhJFRpbWUpLCB5ID0gbWVhbl9wcFtbcF1dLCB5ZW5kID0gbWVhbl9wcFtbcF1dLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgeWF4aXMgPSAieTIiLCBuYW1lPSJBdmcuIFBQIChzdHJhaWdodCkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lPWxpc3QoY29sb3I9ImRhcmtncmF5IiwgZGFzaCA9ICdkb3QnKSkgJT4lCiAgICBhZGRfc2VnbWVudHMoeCA9IG1pbihwRGF0YSRUaW1lKSwgeGVuZCA9IG1heChwRGF0YSRUaW1lKSwgeSA9IG1lYW5fcHBfc2VnMFtbcF1dLCB5ZW5kID0gbWVhbl9wcF9zZWcwW1twXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9ICJ5MiIsIG5hbWU9IkF2Zy4gUFAgKHR1cm5pbmcpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZT1saXN0KGNvbG9yPSJibGFjayIsIGRhc2ggPSAnZG90JykpICU+JQogICAgYWRkX3NlZ21lbnRzKHggPSBtaW4ocERhdGFfc2VnMSRUaW1lKSwgeGVuZCA9IG1heChwRGF0YV9zZWcxJFRpbWUpLCB5ID0gbWVhbl9wcF9zZWcxW1twXV0sIHllbmQgPSBtZWFuX3BwX3NlZzFbW3BdXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gInkyIiwgbmFtZT0iQXZnLiBQUCAoMXN0IHBhcnQpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZT1saXN0KGNvbG9yPSJyZWQiLCBkYXNoID0gJ2RvdCcpKSAlPiUKICAgIGFkZF9zZWdtZW50cyh4ID0gbWluKHBEYXRhX3NlZzIkVGltZSksIHhlbmQgPSBtYXgocERhdGFfc2VnMiRUaW1lKSwgeSA9IG1lYW5fcHBfc2VnMltbcF1dLCB5ZW5kID0gbWVhbl9wcF9zZWcyW1twXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9ICJ5MiIsIG5hbWU9IkF2Zy4gUFAgKDJuZCBwYXJ0KSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmU9bGlzdChjb2xvcj0iZ3JlZW4iLCBkYXNoID0gJ2RvdCcpKSAlPiUKICAgIGFkZF9zZWdtZW50cyh4ID0gbWluKHBEYXRhX3NlZzMkVGltZSksIHhlbmQgPSBtYXgocERhdGFfc2VnMyRUaW1lKSwgeSA9IG1lYW5fcHBfc2VnM1tbcF1dLCB5ZW5kID0gbWVhbl9wcF9zZWczW1twXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9ICJ5MiIsIG5hbWU9IkF2Zy4gUFAgKDNyZCBwYXJ0KSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmU9bGlzdChjb2xvcj0iYmx1ZSIsIGRhc2ggPSAnZG90JykpICU+JQogICAgYWRkX3NlZ21lbnRzKHggPSBtaW4ocERhdGFfc2VnNCRUaW1lKSwgeGVuZCA9IG1heChwRGF0YV9zZWc0JFRpbWUpLCB5ID0gbWVhbl9wcF9zZWc0W1twXV0sIHllbmQgPSBtZWFuX3BwX3NlZzRbW3BdXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gInkyIiwgbmFtZT0iQXZnLiBQUCAoNHRoIHBhcnQpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZT1saXN0KGNvbG9yPSJwdXJwbGUiLCBkYXNoID0gJ2RvdCcpKSAlPiUKICAgIGxheW91dCgKICAgICAgdGl0bGU9cGFzdGUwKCJTdWJqZWN0ICMiLCBwKSwgCiAgICAgIHhheGlzPWxpc3QodGl0bGU9IlRpbWUgW3NdIiwgcmFuZ2U9YygwKSksIAogICAgICB5YXhpcz15MSwgCiAgICAgIHlheGlzMj15MiwgCiAgICAgIG1hcmdpbiA9IGxpc3QobCA9IDUwLCByID0gNTAsIGIgPSA1MCwgdCA9IDUwLCBwYWQgPSA0KSwKICAgICAgbGVnZW5kID0gbGlzdCh4ID0gMC41LCB4YW5jaG9yID0gImNlbnRlciIsIHkgPSAwLjIsIGJnY29sb3IgPSAicmdiYSgwLDAsMCwwKSIsIHRpdGxlPSJNZXRyaWMiLCBvcmllbnRhdGlvbiA9ICJoIiksCiAgICAgIGF1dG9zaXplID0gRgogICAgKQogIAogIHBsdF9BbGxBY2NbW3BdXSA8LSBwbG90X0FjYwp9CgoKaHRtbHRvb2xzOjp0YWdMaXN0KHBsdF9BbGxBY2MpCmBgYAoKCmBgYHtyfQpOVU1CRVJfT0ZfQ0xVU1RFUlMgPSAzCgpjb2xvcl9kYXJrcGluayA9ICIjZTc1NDgwIgpDTFVTVEVSX0JSQU5DSF9DT0xPUlMgPC0gYygiYmx1ZSIsICJkYXJrcmVkIiwgY29sb3JfZGFya3BpbmssICJibGFjayIpWzE6TlVNQkVSX09GX0NMVVNURVJTXQpDTFVTVEVSX0xBQkVMX0NPTE9SUyA8LSBjKCJibHVlIiwgImRhcmtyZWQiLCBjb2xvcl9kYXJrcGluaywgImJsYWNrIilbMTpOVU1CRVJfT0ZfQ0xVU1RFUlNdCgpkZlBQIDwtIGFzLmRhdGEuZnJhbWUoY2JpbmQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnMCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnMSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnMiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnMyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnNCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9tYXgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9zZWcwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX3NlZzEpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfc2VnMiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9zZWczKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX3NlZzQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9tYXgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnMF8xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX3NlZzBfMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9zZWcwXzMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnMF80KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfc2VnMF8xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfc2VnMF8yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfc2VnMF8zKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfc2VnMF80KQogICAgICAgICAgICAgICAgICAgICkpCgpuYW1lcyhkZlBQKSA8LSBjKCJNZWFuUFAiLCAiU3RkUFAiLCAKICAgICAgICAgICAgICAgICAiTWVhblBQX1NlZzAiLCAiTWVhblBQX1NlZzEiLCAiTWVhblBQX1NlZzIiLCAiTWVhblBQX1NlZzMiLCAiTWVhblBQX1NlZzQiLCAiTWVhblBQX1NlZ01heCIsCiAgICAgICAgICAgICAgICAgIlN0ZFBQX1NlZzAiLCAiU3RkUFBfU2VnMSIsICJTdGRQUF9TZWcyIiwgIlN0ZFBQX1NlZzMiLCAiU3RkUFBfU2VnNCIsICJTdGRQUF9TZWdNYXgiLAogICAgICAgICAgICAgICAgICJNZWFuUFBfU2VnMF8xIiwgIk1lYW5QUF9TZWcwXzIiLCAiTWVhblBQX1NlZzBfMyIsICJNZWFuUFBfU2VnMF80IiwKICAgICAgICAgICAgICAgICAiU3RkUFBfU2VnMF8xIiwgIlN0ZFBQX1NlZzBfMiIsICJTdGRQUF9TZWcwXzMiLCAiU3RkUFBfU2VnMF80IikKCmJlaGF2aW9yYWxNYXRyaXhDbHVzdGVyaW5nIDwtIGFzLm1hdHJpeChkZlBQKQoKZGlzdE1hdHJpeCA8LSBkaXN0KGJlaGF2aW9yYWxNYXRyaXhDbHVzdGVyaW5nKQpocmVzdWx0cyA8LSBkaXN0TWF0cml4ICU+JSBoY2x1c3QobWV0aG9kPSJhdmVyYWdlIikKCmhjIDwtIGhyZXN1bHRzICU+JSAKICAgICAgYXMuZGVuZHJvZ3JhbSAlPiUKICAgICAgc2V0KCJub2Rlc19jZXgiLCBOVU1CRVJfT0ZfQ0xVU1RFUlMpICU+JQogICAgICBzZXQoImxhYmVsc19jb2wiLCB2YWx1ZSA9IENMVVNURVJfTEFCRUxfQ09MT1JTLCBrPU5VTUJFUl9PRl9DTFVTVEVSUykgJT4lCiAgICAgICMgc2V0KCJsZWF2ZXNfcGNoIiwgMTkpICU+JQogICAgICAjIHNldCgibGVhdmVzX2NvbCIsIHZhbHVlID0gYygiZ3JheSIpLCBrPU5VTUJFUl9PRl9DTFVTVEVSUykgJT4lICAgIAogICAgICBzZXQoImJyYW5jaGVzX2tfY29sb3IiLCB2YWx1ZT1DTFVTVEVSX0JSQU5DSF9DT0xPUlMsIGs9TlVNQkVSX09GX0NMVVNURVJTKQoKcGxvdChoYykKbGVnZW5kKCJ0b3ByaWdodCIsIAogICAgIHRpdGxlPSJEcml2ZT1Nb3RvcmljIFxuSGllcmFjaGljYWwgQ2x1c3RlcmluZyIsCiAgICAgbGVnZW5kID0gYygiR3JvdXAgMSIsICJHcm91cCAyIiwgIkdyb3VwIDMiKSwgCiAgICAgY29sID0gYygiZGFya3JlZCIsICJwaW5rIiAsICJibHVlIiksCiAgICAgcGNoID0gYygyMCwyMCwyMCksIGJ0eSA9ICJuIiwgIHB0LmNleCA9IDEuNSwgY2V4ID0gMC44ICwgCiAgICAgdGV4dC5jb2wgPSAiYmxhY2siLCBob3JpeiA9IEZBTFNFLCBpbnNldCA9IGMoMC40LCAwLjEpKQpgYGAKCiMgQ2x1c3RlcmluZyB3aXRoIFNEIG9mIFBQCmBgYHtyfQpsaWJyYXJ5KGRlbmRleHRlbmQpCgpjbHVzdGVyaW5nRGYgPC0gZGZQUCAlPiUgc2VsZWN0KFN0ZFBQKQpOVU1CRVJfT0ZfQ0xVU1RFUlMgPSAzCgpjb2xvcl9kYXJrcGluayA9ICIjZTc1NDgwIgpDTFVTVEVSX0JSQU5DSF9DT0xPUlMgPC0gYygiZGFya3JlZCIsICJibHVlIiwgInJlZCIpWzE6TlVNQkVSX09GX0NMVVNURVJTXQpDTFVTVEVSX0xBQkVMX0NPTE9SUyA8LSBjKCJkYXJrcmVkIiwgImJsdWUiLCAicmVkIilbMTpOVU1CRVJfT0ZfQ0xVU1RFUlNdCgpiZWhhdmlvcmFsTWF0cml4Q2x1c3RlcmluZyA8LSBhcy5tYXRyaXgoY2x1c3RlcmluZ0RmKQpyb3duYW1lcyhiZWhhdmlvcmFsTWF0cml4Q2x1c3RlcmluZykgPC0gcGFzdGUwKCIjIiwgcGVyc29ucykKZGlzdE1hdHJpeCA8LSBkaXN0KGJlaGF2aW9yYWxNYXRyaXhDbHVzdGVyaW5nKQpocmVzdWx0cyA8LSBkaXN0TWF0cml4ICU+JSBoY2x1c3QKCmhjIDwtIGhyZXN1bHRzICU+JSAKICAgICAgYXMuZGVuZHJvZ3JhbSAlPiUKICAgICAgc2V0KCJub2Rlc19jZXgiLCBOVU1CRVJfT0ZfQ0xVU1RFUlMpICU+JQogICAgICBzZXQoImxhYmVsc19jb2wiLCB2YWx1ZSA9IENMVVNURVJfTEFCRUxfQ09MT1JTLCBrPU5VTUJFUl9PRl9DTFVTVEVSUykgJT4lCiAgICAgICMgc2V0KCJsZWF2ZXNfcGNoIiwgMTkpICU+JQogICAgICAjIHNldCgibGVhdmVzX2NvbCIsIHZhbHVlID0gYygiZ3JheSIpLCBrPU5VTUJFUl9PRl9DTFVTVEVSUykgJT4lICAgIAogICAgICBzZXQoImJyYW5jaGVzX2tfY29sb3IiLCB2YWx1ZT1DTFVTVEVSX0JSQU5DSF9DT0xPUlMsIGs9TlVNQkVSX09GX0NMVVNURVJTKQoKcGxvdChoYykKbGVnZW5kKCJ0b3ByaWdodCIsIAogICAgIHRpdGxlPSJEcml2ZT1Nb3RvcmljIFxuQ2hhbmdlIG9mIEFyb3VzYWwiLAogICAgIGxlZ2VuZCA9IGMoIkV4Y2VwdGlvbmFsIFNEIiAsICJMb3cgU0QiICwgIkhpZ2ggU0QiKSwgCiAgICAgY29sID0gYygiZGFya3JlZCIsICJibHVlIiAsICJyZWQiKSwKICAgICBwY2ggPSBjKDIwLDIwLDIwKSwgYnR5ID0gIm4iLCAgcHQuY2V4ID0gMS41LCBjZXggPSAwLjggLCAKICAgICB0ZXh0LmNvbCA9ICJibGFjayIsIGhvcml6ID0gRkFMU0UsIGluc2V0ID0gYygwLjAsIDAuMSkpCmBgYAoKYGBge3J9CmxpYnJhcnkoY2x1c3RlcikKc2lsaG91ZXR0ZV9zY29yZSA8LSBmdW5jdGlvbihrKXsKICBrbSA8LSBrbWVhbnMoY2x1c3RlcmluZ0RmLCBjZW50ZXJzID0gaywgbnN0YXJ0PTI1KQogIHNzIDwtIHNpbGhvdWV0dGUoa20kY2x1c3RlciwgZGlzdChjbHVzdGVyaW5nRGYpKQogIG1lYW4oc3NbLCAzXSkKfQprIDwtIDI6MTAKYXZnX3NpbCA8LSBzYXBwbHkoaywgc2lsaG91ZXR0ZV9zY29yZSkKcGxvdChrLCB0eXBlPSdiJywgYXZnX3NpbCwgeGxhYj0nTnVtYmVyIG9mIGNsdXN0ZXJzJywgeWxhYj0nQXZlcmFnZSBTaWxob3VldHRlIFNjb3JlcycsIGZyYW1lPUZBTFNFKQpgYGAKCmBgYHtyfQojIFN0b3JlIGNsdXN0ZXJpbmcgZGF0YQpmUGF0aCA8LSBzdHJfaW50ZXJwKCIuLi9kYXRhL3Byb2Nlc3NlZC9hbmFseXNpcy9UVDFfRHJpdmVfM19QUC5jc3YiKQpkZnggPC0gZGZQUApkZnggPC0gY2JpbmQocGVyc29ucywgZGZ4KQpuYW1lcyhkZngpIDwtIGMoIlN1YmplY3QiICwgbmFtZXMoZGZQUCkpCndyaXRlLmNzdihkZngsIGZQYXRoLCByb3cubmFtZXMgPSBGKQpgYGAKCgo=